﻿#region

using System;
using System.Linq;
using System.Web.Mvc;
using Tateeda.ClinicalStudy.Base.Modules.Common.Enumeration;
using Tateeda.ClinicalStudy.Base.Modules.Common.Extenstions;
using Tateeda.ClinicalStudy.Base.Modules.Infrastructure.Interfaces.Services;
using Tateeda.ClinicalStudy.Base.Modules.Models.StudyForm;
using Tateeda.ClinicalStudy.Base.Modules.Models.User;
using Tateeda.ClinicalStudy.Base.Web.Common;

#endregion

#region - Legal -

///<legal>
/// Copyright © 2011, Tateeda Media Network
/// All rights reserved. http://tateeda.com
///
/// Redistribution and use in source and binary forms, with or without
/// modification, are permitted provided that the following conditions
/// are met:
///
/// - Redistributions of source code must retain the above copyright
/// notice, this list of conditions and the following disclaimer.
///
/// - Neither the name of the Tateeda Media Network, nor the names of its
/// contributors may be used to endorse or promote products
/// derived from this software without specific prior written
/// permission.
///
/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
/// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
/// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
/// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES INCLUDING,
/// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
/// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
/// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
/// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
/// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
/// POSSIBILITY OF SUCH DAMAGE.
///</legal>

#endregion - Legal -

namespace Tateeda.ClinicalStudy.Base.Web.Controllers {

    public class StudyFormController : Controller {
        private readonly IStudyService _service;

        public StudyFormController(IStudyService service) {
            _service = service;
        }

        /// <summary>
        ///   Forms the specified appt id.
        /// </summary>
        /// <param name = "apid">The appointment id.</param>
        /// <param name = "fid">The form id to fill.</param>
        /// <returns></returns>
        [ValidateAntiForgeryToken]
        [Authorize(Roles = Constants.RoleAdminAppuser)]
        public ActionResult Form(int apid, int fid) {
            var appt = _service.GetAppointment(apid);
            var form = _service.GetFormWithAnswers(fid, appt.SubjectId);
            ViewBag.FormQuestions = form.Questions.ToQuestionModelList();
            ViewBag.LayoutType = form.LayoutType.HasValue ? form.LayoutType.Value : 0;
            ViewBag.AppointmentId = apid;
            var apptForm = appt.AppointmentForms.Where(af => af.FormId == fid).FirstOrDefault();
            ViewBag.AppointmentFormId = apptForm != null ? apptForm.AppointmentFormId : 0;
            if (Request.UrlReferrer != null) ViewBag.ReturnTo = Request.UrlReferrer.AbsoluteUri;
            return View(form);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize(Roles = Constants.RoleAdminAppuser)]
        public RedirectResult SaveContinue(FormCollection form, int formId, int apid, string returnTo) {
            SaveToDB(form, formId, apid);
            //Set status:
            SetAppointmentFormStatus(apid, formId, StudyStatus.InProgressStatus);
            return RedirectPermanent(returnTo);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize(Roles = Constants.RoleAdminAppuser)]
        public RedirectResult SaveFinish(FormCollection form, int formId, int apid, string returnTo) {
            SaveToDB(form, formId, apid);
            //Set Status
            SetAppointmentFormStatus(apid, formId, StudyStatus.CompletedStatus);
            return RedirectPermanent(returnTo);
        }

        #region - Private Helper functions -

        private void SaveToDB(FormCollection form, int formId, int apid) {
            var appUser = _service.GetAppUserByName(User.Identity.Name);
            //DO IT ONLY ONCE to clear existing answers. We do not do updates, we do delete and insert here.
            _service.DeleteFormAnswers(formId, apid);
            foreach (var key in form.AllKeys) {
                if (key.IndexOf("Question_") == 0) {
                    var quesiontId = key.Split(new[] { "Question_" }, StringSplitOptions.RemoveEmptyEntries)[0];
                    if (quesiontId != null) {
                        var answers = form[key].Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                        _service.SaveFormAnswers(formId, apid, quesiontId, answers, appUser);
                    }
                }
            }
        }

        private void SetAppointmentFormStatus(int apid, int formId, StudyStatus status) {
            var appUser = _service.GetAppUserByName(User.Identity.Name);
            var appt = _service.GetAppointment(apid);
            var apptForm = appt.AppointmentForms.Where(af => af.FormId == formId).FirstOrDefault();
            var appointementFormId = apptForm != null ? apptForm.AppointmentFormId : 0;

            _service.SetAppointmentFormStatus(appointementFormId, status.ToStatusInt(), appUser);
        }

        #endregion - Private Helper functions -
    }
}